/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"


/******************************************************************************
// Name:            ijxDecompressInit
// Description:     Init function for JPEG decompress.
// Input Arguments:
// nDesiredImageMode:
//                   Specifies desired output image mode.
//                   IIP_CM_GRAY/IIP_CM_BGR/IIP_CM_BGRA/IIP_CM_BGR555/IIP_CM_BGR565, etc
//                   IIP_CM_BGR555/IIP_CM_BGR565 are not support in IPP JPEG version 1.x
//   nOperationMode: Specifies operation mode for single or multiple image.
//                   IJX_OP_SINGLE/IJX_OP_MULTIPLE.
// Output Arguments:
//          pStream: Points to IJBITTREAMSTATE structure.
//     pDecodeState: Points to IJDECODESTATE structure.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_NOTSUPPORTMARKER
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijxDecompressInit (int nDesiredImageMode,
                             int nOperationMode,
                             IJBITTREAMSTATE *pStream,
                             IJDECODESTATE *pDecodeState)
{
    int marker;
    IJXRESULT rtCode;

    pDecodeState->nLastMarker  = IJX_MARKER_NONE;
    pDecodeState->nRstInterval = 0;
    pDecodeState->counter.nScanCounter=0;
    pDecodeState->counter.nFrameScanCounter=0;
    pDecodeState->counter.nTotalFrameCounter=0;
    pDecodeState->counter.nProcessedBitsLen=0;
    pDecodeState->nStatus=IJX_STATUS_START;
    pDecodeState->nDesiredImageMode=nDesiredImageMode;
    pDecodeState->nOperationMode=nOperationMode;
    pDecodeState->nJPEGCodeMode=IJX_MODE_NONE;

    pDecodeState->timeSpec.nFlags=0;
    pDecodeState->timeSpec.nTimeCounter=0;

    pStream->nMarker=IJX_MARKER_NONE;
    pStream->nNumValidPrefetchedBits=0;
    pStream->nPrefetchedBits=0;

    /* Parse SOI */
    rtCode=ijReadMarker(&marker, pStream);
    if (!IJX_SUCCEEDED(rtCode)||IJX_MARKER_SOI!=marker){
        return IJX_RTCODE_E_ERRPARSE;
    }

    ijBuildDefaultDecodeTables(pDecodeState);

    /* Read Next Frame */
    pDecodeState->nDesiredMarker=IJX_MARKER_SOF;
    rtCode=ijParseTablesMisc(pStream, pDecodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    }

    if (IJX_RTCODE_S_EOF==rtCode) {
       return IJX_RTCODE_S_EOF;
    }

    rtCode=ijPreprocessMarker(pStream, pDecodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    }

    rtCode=ijCalcDecBufferSize(pDecodeState->nJPEGCodeMode,
                               pDecodeState->imageSpec.nNumComponent, 
                               &(pDecodeState->mcuSpec),
                               &(pDecodeState->bufSpec) );

    if (!IJX_SUCCEEDED(rtCode)){
        return rtCode;
    }

    return rtCode;
}

/******************************************************************************
// Name:            ijxGetDecompBufLen
// Description:     Use this function to get desired buffer length for decoding
// Input Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.
// Output Arguments:
//         pnBufLen: Points to int type that define buffer length in byte.
//                  
******************************************************************************/
IJXRESULT ijxGetDecompBufLen (int *pnBufLen, 
                              IJDECODESTATE *pDecodeState)
{
    *pnBufLen=0;

    if (pnBufLen&&pDecodeState) {
        *pnBufLen=pDecodeState->bufSpec.nMaxBufLen;
        return IJX_RTCODE_OK;
    }
    return IJX_RTCODE_E_ERRPARAM;
}

/******************************************************************************
// Name:            ijxDecompBufInit
// Description:     Initialize all internal buffer for decoding.
// Input Arguments: 
//         pBufPtr: Points to internal buffer which allocated by codec caller. 
//        nBuffLen: Specifies the buffer length which is identified by pBufPtr.
// Output Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
// Returns:          
//                     
//                  
******************************************************************************/
IJXRESULT ijxDecompBufInit(void *pBufPtr, 
                           int  nBufLen,
                           IJDECODESTATE *pDecodeState)
{
    IJXRESULT rtCode;
    rtCode=ijInitBuffers( pBufPtr, nBufLen,
                         &(pDecodeState->bufSpec),
                         &(pDecodeState->mcuSpec),
                         &(pDecodeState->imageSpec) );
    return rtCode;
}

/******************************************************************************
// Name:            ijxDecompress
// Description:     Decompress JPEG image from code stream.
// Input Arguments:
//      ppImageBuf: Points to image buffer pointers.
//  pnImageBufStep: Points to array of image buffer step.
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_NOTSUPPORTMARKER
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijxDecompress (void     **ppImageBuf,
                         int      *pnImageBufStep,  
                         IJBITTREAMSTATE *pStream,
                         IJDECODESTATE *pDecodeState)
{
    IJXRESULT rtCode;

    if (!(IJX_MODE_PROGRESSIVE&pDecodeState->nJPEGCodeMode)) {
        rtCode=ijParseTablesMisc(pStream, pDecodeState);
        if (!IJX_SUCCEEDED(rtCode)) {
            return rtCode;
        }

        if (IJX_RTCODE_S_EOF==rtCode) {
           return IJX_RTCODE_S_EOF;
        }

        rtCode=ijPreprocessMarker(pStream, pDecodeState);
        if (!IJX_SUCCEEDED(rtCode)) {
            return rtCode;
        }
    }

    pDecodeState->bufSpec.paImageBuf[0]=ppImageBuf[0];
    pDecodeState->bufSpec.paImageBufCur[0]=ppImageBuf[0];
    pDecodeState->bufSpec.naImageStep[0]=pnImageBufStep[0];

    rtCode=pDecodeState->procSpec.funcDecompress(pStream, pDecodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        return rtCode;
    }

    if (IJX_RTCODE_S_EOF==rtCode) {
        /* MCU Counter */
//        pDecodeState->counter.nFrameMCUCounter+=pDecodeState->counter.nScanMCUCounter;
//        pDecodeState->counter.nTotalMCUCounter+=pDecodeState->counter.nScanMCUCounter;

        /* Scan Counter */
        pDecodeState->counter.nFrameScanCounter=pDecodeState->counter.nScanCounter;
//        pDecodeState->counter.nTotalScanCounter+=pDecodeState->counter.nScanCounter;
    }

    return rtCode;
}

/******************************************************************************
// Name:            ijxGetWaveStream
// Description:     Find the wave stream 
// Input Arguments:
// ppWaveStreamBuf: Points to wave stream pointer.
//         pStream: Identifies IJBITTREAMSTATE data structure.
// Output Arguments:
//    pnByteLength: Points to int data type to specifies the length of wave stream in byte. 
//                  
******************************************************************************/
IJXRESULT ijxGetWaveStream(void **ppWaveStreamBuf,
                           int  *pnByteLength,
                           IJBITTREAMSTATE *pStream)
{
    return ijGetWaveStream(ppWaveStreamBuf, pnByteLength, pStream);
}

/******************************************************************************
// Name:            ijxGetTimeStamp
// Description:     Get Time Stamp from code stream.
// Input Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
// Output Arguments:
//       ppTimeSpec: Points to the pointer of  IJTIMESPEC data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijxGetTimeStamp(IJTIMESPEC      **ppTimeSpec,
                          IJDECODESTATE   *pDecodeState)
{
    *ppTimeSpec = &(pDecodeState->timeSpec);
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijxGetDecompressImageSpec
// Description:     Get Image parameters from code stream.
// Input Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
// Output Arguments:
//      ppImageSpec: Points to the pointer of  IIPIMAGESPEC data structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijxGetDecompressImageSpec(IIPIMAGESPEC **ppImageSpec,
                                    IJDECODESTATE *pDecodeState)
{
    *ppImageSpec=&(pDecodeState->imageSpec);
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijGetDecompressWaveSpec
// Description:     Get Wave parameters
// Input Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
// Output Arguments:
//       ppWaveSpec: Points to the pointer of IWPWAVESPEC structure.
//                     
//                  
******************************************************************************/
IJXRESULT ijxGetDecompressWaveSpec(IWPWAVESPEC  **ppWaveSpec, 
                                   IJDECODESTATE *pDecodeState)
{
    *ppWaveSpec=&(pDecodeState->waveSpec);
    return IJX_RTCODE_OK;
}

/******************************************************************************
// Name:            ijGetDecompressMotionSpec
// Description:     Get Motion JPEG parameters from code stream
// Input Arguments: 
//     pDecodeState: Points to IJDECODESTATE structure.   
// Output Arguments:
//     ppMotionSpec: Points to IJMOTIONSPEC structure
//                     
//                  
******************************************************************************/
IJXRESULT ijxGetDecompressMotionSpec(IJMOTIONSPEC **ppMotionSpec, 
                                     IJDECODESTATE *pDecodeState)
{
    *ppMotionSpec=&(pDecodeState->motionSpec);
    return IJX_RTCODE_OK;
}


/******************************************************************************
// Name:            ijxIsInMotionDecoding
// Description:     Use this function to check current status if it is in motion decoding 
// Input Arguments:
//     pDecodeState: Points to IJDECODESTATE structure.   
// Output Arguments:
//                  
******************************************************************************/
IJXRESULT ijxIsInMotionDecoding(IJDECODESTATE *pDecodeState)
{
    if (IJX_MODE_MOTION_MASK&pDecodeState->nJPEGCodeMode){
        return IJX_RTCODE_OK;
    }
    return IJX_RTCODE_NO;
}

/* EOF */
                
